package com.ericsson.smart.model;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;

public class Report implements Serializable {

	private static final long serialVersionUID = 3556606716416274086L;

	private String name;

	//private int dimensionCount;

	private String aggregateOperation;

	private List<String> dimensionList;

	private Map<String, Dimension> dimensionMap;

	private Map<String, BreadCrumb> breadCrumbMap;

	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}

	public int getDimensionCount() {
		//commented for dimension swap
		//return dimensionCount;
		return dimensionList.size();
	}

//	public void setDimensionCount(int dimensionCount) {
//		this.dimensionCount = dimensionCount;
//	}

	public Map<String, Dimension> getDimensionMap() {
		return dimensionMap;
	}

	public void setDimensionMap(Map<String, Dimension> dimensionMap) {
		this.dimensionMap = dimensionMap;
	}

	public Map<String, BreadCrumb> getBreadCrumbMap() {
		return breadCrumbMap;
	}

	public String getAggregateOperation() {
		return aggregateOperation;
	}

	public void setAggregateOperation(String aggregateOperation) {
		this.aggregateOperation = aggregateOperation;
	}

	public List<String> getDimensionList() {
		// commented later for dimension swapping
		/*
		 * List<String> dimensionList = new ArrayList<String>(); for (Entry<String, Dimension>
		 * dimension : dimensionMap.entrySet()) { dimensionList.add(dimension.getValue().getName());
		 * } return dimensionList;
		 */
		return dimensionList;
	}

	public List<Map<String, Object>> getDimensionDataMapList() {
		// commented later for dimension swapping
		/*
		 * List<Map<String, Object>> dimensionDataMapList = new ArrayList<Map<String, Object>>();
		 * for (Entry<String, BreadCrumb> breadCrumb : breadCrumbMap.entrySet()) {
		 * //System.out.println("xxx-"+breadCrumb.getValue().getDimensionValueMap());
		 * dimensionDataMapList.add(breadCrumb.getValue().getDimensionValueMap()); } return
		 * dimensionDataMapList;
		 */
		System.out.println("Inside getDimensionDataMapList() method...");
		List<Map<String, Object>> dimensionDataMapList = new ArrayList<Map<String, Object>>();
		for (String dimensionName : dimensionList) {
			dimensionDataMapList.add(breadCrumbMap.get(dimensionName).getDimensionValueMap());
		}
		return dimensionDataMapList;
	}

	public void addDimension(Dimension dimension) {
		System.out.println("Inside addDimension() method..... ");
		if (dimensionMap == null) {
			dimensionMap = new LinkedHashMap<String, Dimension>();
		}
		this.dimensionMap.put(dimension.getName(), dimension);
		addBreadCrumb(dimension.getName(), dimension.getCurrentSelectionName(),
				dimension.getCurrentSelectionValue());

		// added later for dimension swapping
		if (dimensionList == null) {
			dimensionList = new ArrayList<String>();
		}
		if(!dimensionList.contains(dimension.getName())) {
			dimensionList.add(dimension.getName());
		}		
	}

	public void updateDimension(Dimension dimension) {
		addDimension(dimension);
	}
	
	public void setAsFirstDimension(String dimName) {
		if(dimensionList.contains(dimName)) {
			dimensionList.remove(dimName);
			dimensionList.add(0, dimName);
		}		
	}

	public Dimension getDimension(String dimName) {
		System.out.println("Inside getDimension() method...");
		if (!dimensionMap.containsKey(dimName.trim())) {
			return null;
		} else {
			for (Entry<String, Dimension> dimension : dimensionMap.entrySet()) {
				if (dimension.getKey().equals(dimName)) {
					System.out.println("dimension.getValue()....."+dimension.getValue());
					return dimension.getValue();
				}
			}
			return null;
		}
	}

	public void removeDimension(String dimName) {
		if (dimensionMap != null) {
			if (dimensionMap.containsKey(dimName.trim())) {
				dimensionMap.remove(dimName.trim());
				if (breadCrumbMap != null) {
					if (breadCrumbMap.containsKey(dimName.trim())) {
						breadCrumbMap.remove(dimName.trim());
						if (dimensionList.contains(dimName)) {
							dimensionList.remove(dimName);
						}
					}
				}
			}
		}
	}

	public void addBreadCrumb(String dimName, String levelName, Object levelValue) {
		BreadCrumb breadCrumb;
		if (breadCrumbMap == null) {
			breadCrumbMap = new LinkedHashMap<String, BreadCrumb>();
		}
		if (!breadCrumbMap.containsKey(dimName)) {
			breadCrumb = new BreadCrumb();
			breadCrumb.setDimension(dimName);
		} else {
			breadCrumb = breadCrumbMap.get(dimName);
		}
		breadCrumb.addValueToBreadCrumb(levelName, levelValue);
		breadCrumbMap.put(dimName, breadCrumb);
	}

	public BreadCrumb getBreadCrumb(String dimName) {
		if (breadCrumbMap == null) {
			return null;
		}
		if (!breadCrumbMap.containsKey(dimName)) {
			return null;
		}
		return breadCrumbMap.get(dimName);
	}

	public void updateBreadCrumb(String dimName, String levelName, String levelValue) {
		addBreadCrumb(dimName, levelName, levelValue);
	}

	public void updateBreadCrumb(String dimName, LinkedHashMap<String, Object> newBreadCrumb) {
		System.out.println("Inside updateBreadCrumb() method....");
		System.out.println("dimName is...."+dimName);
		BreadCrumb breadCrumb;
		if (breadCrumbMap == null) {
			System.out.println("Enter breadCrumbMap is null........");
			breadCrumbMap = new LinkedHashMap<String, BreadCrumb>();
		}
		if (!breadCrumbMap.containsKey(dimName)) {
			System.out.println("Enter breadCrumbMap is not null.....if block........");
			breadCrumb = new BreadCrumb();
			breadCrumb.setDimension(dimName);
		} else {
			System.out.println("Enter breadCrumbMap is not null.....else block........");
			breadCrumb = breadCrumbMap.get(dimName);
		}
		breadCrumb.updateBreadCrumb(newBreadCrumb);
	}

	public void removeBreadCrumb(String dimName, String levelName) {
		BreadCrumb breadCrumb;
		if (breadCrumbMap != null) {
			if (breadCrumbMap.containsKey(dimName)) {
				breadCrumb = breadCrumbMap.get(dimName);
				breadCrumb.removeFromBreadCrumb(levelName);
				breadCrumbMap.put(dimName, breadCrumb);
			}
		}
	}

	public void removeBreadCrumb(String dimName) {
		if (breadCrumbMap != null) {
			if (breadCrumbMap.containsKey(dimName)) {
				breadCrumbMap.remove(dimName);
			}
		}
	}

//	public String toString() {
//		StringBuffer output = new StringBuffer();
//		output.append("\n --------REPORT DETAILS---------\n NAME: " + name
//				+ "\n AGGREGATE-OPERATION: " + aggregateOperation + "\n DIMENSION-COUNT: "
//				+ dimensionList.size() + "\n ------------------------------");
////				+ dimensionCount + "\n ------------------------------");
//		for (Entry<String, Dimension> dimension : dimensionMap.entrySet()) {
//			output.append("\n " + dimension);
//			output.append("\n " + breadCrumbMap.get(dimension.getKey()));
//		}
//		return output.toString();
//	}
	
	public String toString() {
		StringBuffer output = new StringBuffer();
		output.append("\n --------REPORT DETAILS---------\n NAME: " + name
				+ "\n AGGREGATE-OPERATION: " + aggregateOperation + "\n DIMENSION-COUNT: "
				+ dimensionList.size() + "\n ------------------------------");
//				+ dimensionCount + "\n ------------------------------");
		for(String dimName:dimensionList) {
			Dimension dimension = dimensionMap.get(dimName);
			output.append("\n " + dimension);
			output.append("\n " + breadCrumbMap.get(dimension.getName()));
		}
		return output.toString();
	}
}
